﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;

namespace ScrumFactory.Windows.Helpers.Extensions {

    public static class VisualTreeExtensions {
        public static T GetVisualAncestor<T>(this DependencyObject d) where T : class {

            if (!(d is Visual) && !(d is System.Windows.Media.Media3D.Visual3D))
                return null;

            DependencyObject item = VisualTreeHelper.GetParent(d);

            while (item != null) {
                T itemAsT = item as T;
                if (itemAsT != null) return itemAsT;
                item = VisualTreeHelper.GetParent(item);
            }

            return null;
        }

        public static DependencyObject GetVisualAncestor(this DependencyObject d, Type type) {
            DependencyObject item = VisualTreeHelper.GetParent(d);

            while (item != null) {
                if (item.GetType() == type) return item;
                item = VisualTreeHelper.GetParent(item);
            }

            return null;
        }

        public static T GetVisualDescendent<T>(this DependencyObject d) where T : DependencyObject {
            return d.GetVisualDescendents<T>().FirstOrDefault();
        }

        public static IEnumerable<T> GetVisualDescendents<T>(this DependencyObject d) where T : DependencyObject {
            int childCount = VisualTreeHelper.GetChildrenCount(d);

            for (int n = 0; n < childCount; n++) {
                DependencyObject child = VisualTreeHelper.GetChild(d, n);

                if (child is T) {
                    yield return (T)child;
                }

                foreach (T match in GetVisualDescendents<T>(child)) {
                    yield return match;
                }
            }

            yield break;
        }
    }
}
